#!/bin/sh
### BEGIN INIT INFO
# Provides:                     openvpn
# Required-Start:               $network
# Required-Stop:                $network
# Default-Start:                3 5
# Default-Stop:                 0 1 2 6
# Short-Description:            This shell script takes care of starting and stopping OpenVPN.
# Description:                  OpenVPN is a robust and highly flexible tunneling application that uses all of the encryption, authentication, and certification features of the OpenSSL library to securely tunnel IP networks over a single UDP port. 
### END INIT INFO

# Contributed to the OpenVPN project by
# Douglas Keller <doug@voidstar.dyndns.org>
# 2002.05.15

# Modified for SuSE by
# Frank Plohmann <openvpn@franks-planet.de>
# 2003.08.24
# Please feel free to contact me if you have problems or suggestions
# using this script.

# To install:
#   copy this file to /etc/rc.d/init.d/openvpn
#   use the runlevel editor in Yast to add it to runlevel 3 and/or 5
#   shell> mkdir /etc/openvpn
#   make .conf or .sh files in /etc/openvpn (see below)

# To uninstall:
#   use also Yast and the runlevel editor to uninstall

# Author's Notes:
#
# I have created an /etc/init.d init script and enhanced openvpn.spec to
# automatically register the init script.  Once the RPM is installed you
# can start and stop OpenVPN with "service openvpn start" and "service
# openvpn stop".
#
# The init script does the following:
#
# - Starts an openvpn process for each .conf file it finds in
#   /etc/openvpn.
#
# - If /etc/openvpn/xxx.sh exists for a xxx.conf file then it executes
#   it before starting openvpn (useful for doing openvpn --mktun...).
#
# - In addition to start/stop you can do:
#
#   /etc/init.d/openvpn reload - SIGHUP
#   /etc/init.d/openvpn reopen - SIGUSR1
#   /etc/init.d/openvpn status - SIGUSR2

# Modifications 2003.05.02
#   * Changed == to = for sh compliance (Bishop Clark).
#   * If condrestart|reload|reopen|status, check that we were
#     actually started (James Yonan).
#   * Added lock, piddir, and work variables (James Yonan).
#   * If start is attempted twice, without an intervening stop, or
#     if start is attempted when previous start was not properly
#     shut down, then kill any previously started processes, before
#     commencing new start operation (James Yonan).
#   * Do a better job of flagging errors on start, and properly
#     returning success or failure status to caller (James Yonan).
#
# Modifications 2003.08.24
#   * Converted the script for SuSE Linux distribution. 
#	  Tested with version 8.2 (Frank Plohmann).
#		- removed "chkconfig" header
#		- added Yast header
#		- changed installation notes
#		- corrected path to openvpn binary
#		- removes sourcing "functions"
#		- removed sourcing "network"
#		- removed network checking. it seemed not to work with SuSE.
#		- added sourcing "rc.status", comments and "rc_reset" command
#		- removed "succes; echo" and "failure; echo" lines
#		- added "rc_status" lines at the end of each section
#		- changed "service" to "/etc/init.d/" in "In addition to start/stop"
#		  section above.
#
# Modifications 2005.04.04
#   * Added openvpn-startup and openvpn-shutdown script calls (James Yonan).
#

# Location of openvpn binary
openvpn="/usr/sbin/openvpn"

# Lockfile
lock="/var/lock/subsys/openvpn"

# PID directory
piddir="/var/run/openvpn"

# Our working directory
work=/etc/openvpn

# Source rc functions
. /etc/rc.status

# Shell functions sourced from /etc/rc.status:
#      rc_check         check and set local and overall rc status
#      rc_status        check and set local and overall rc status
#      rc_status -v     ditto but be verbose in local rc status
#      rc_status -v -r  ditto and clear the local rc status
#      rc_failed        set local and overall rc status to failed
#      rc_reset         clear local rc status (overall remains)
#      rc_exit          exit appropriate to overall rc status

#      rc_status        check and set local and overall rc status
#      rc_status -v     ditto but be verbose in local rc status
#      rc_status -v -r  ditto and clear the local rc status
#      rc_failed        set local and overall rc status to failed
#      rc_reset         clear local rc status (overall remains)
#      rc_exit          exit appropriate to overall rc status

# First reset status of this service
rc_reset

[ -f  $openvpn ] || exit 0

# See how we were called.
case "$1" in
  start)
	echo -n $"Starting openvpn: "

	/sbin/modprobe tun >/dev/null 2>&1

	# From a security perspective, I think it makes
	# sense to remove this, and have users who need
	# it explictly enable in their --up scripts or
	# firewall setups.

	#echo 1 > /proc/sys/net/ipv4/ip_forward

	# Run startup script, if defined
	if [ -f $work/openvpn-startup ]; then
	    $work/openvpn-startup
	fi

	if [ ! -d  $piddir ]; then
	    mkdir $piddir
	fi

	if [ -f $lock ]; then
	    # we were not shut down correctly
	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
	      if [ -s $pidf ]; then
		kill `cat $pidf` >/dev/null 2>&1
	      fi
	      rm -f $pidf
	    done
	    rm -f $lock
	    sleep 2
	fi

	rm -f $piddir/*.pid
	cd $work

	# Start every .conf in $work and run .sh if exists
	errors=0
	successes=0
	for c in `/bin/ls *.conf 2>/dev/null`; do
	    bn=${c%%.conf}
	    if [ -f "$bn.sh" ]; then
		. ./$bn.sh
	    fi
	    rm -f $piddir/$bn.pid
	    $openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work
	    if [ $? = 0 ]; then
		successes=1
	    else
		errors=1
	    fi
	done

	if [ $successes = 1 ]; then
	    touch $lock
	fi

	rc_status -v
	;;
  stop)
	echo -n $"Shutting down openvpn: "
	for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
	  if [ -s $pidf ]; then
	    kill `cat $pidf` >/dev/null 2>&1
	  fi
	  rm -f $pidf
	done

	# Run shutdown script, if defined
	if [ -f $work/openvpn-shutdown ]; then
	    $work/openvpn-shutdown
	fi

	rm -f $lock

	rc_status -v
	;;
  restart)
	$0 stop
	sleep 2
	$0 start

	rc_status
	;;
  reload)
	if [ -f $lock ]; then
	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
		if [ -s $pidf ]; then
		    kill -HUP `cat $pidf` >/dev/null 2>&1
		fi
	    done
	else
	    echo "openvpn: service not started"
	    exit 1
	fi

	rc_status -v
	;;
  reopen)
	if [ -f $lock ]; then
	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
		if [ -s $pidf ]; then
		    kill -USR1 `cat $pidf` >/dev/null 2>&1
		fi
	    done
	else
	    echo "openvpn: service not started"
	    exit 1
	fi

	rc_status -v
	;;
  condrestart)
	if [ -f $lock ]; then
	    $0 stop
	    # avoid race
	    sleep 2
	    $0 start
	fi

	rc_status
	;;
  status)
	if [ -f $lock ]; then
	    for pidf in `/bin/ls $piddir/*.pid 2>/dev/null`; do
		if [ -s $pidf ]; then
		    kill -USR2 `cat $pidf` >/dev/null 2>&1
		fi
	    done
	    echo "Status written to /var/log/messages"
	else
	    echo "openvpn: service not started"
	    exit 1
	fi

	rc_status -v
        ;;
  *)
	echo "Usage: openvpn {start|stop|restart|condrestart|reload|reopen|status}"
	exit 1
esac

exit 0
